/**
 * 该函数解决每个async await都加try catch 的麻烦
 * @param promise 需要一个Promise对象
 * @returns 返回一个Promise 数组，第一项为result, 第二项为error
 */
export const toPromise = <T>(promise: Promise<T>):  Promise<[Error | null, T | undefined]> => {
    return promise
    .then<[null, T]>((data: T) => [null, data])
    .catch<[Error, undefined]>((err: Error) => [err, undefined])
}

/**
 * 数字千分位分隔符
 * @param num 需要进行千分位的数字
 * @returns 返回一个通过逗号分割的数字字符串
 */
export const thousandSeparator = (num: number) => {
    if (!num) return ''
    // 将数字转为字符串，并分割整数和小数部分
    const parts = num.toString().split('.');
    let integerPart = parts[0];
    const decimalPart = parts.length > 1 ? '.' + parts[1] : '';
    // 处理整数部分
    integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");

    return integerPart + decimalPart;
}

/**
 * 创建一个防抖函数，该函数返回一个 Promise
 * @param func 需要防抖的原始函数
 * @param delay 防抖延迟时间（毫秒）
 * @returns 防抖后的函数，该函数返回一个 Promise
 */
export function debouncePromise<T extends (...args: any[]) => any>(func: T, delay: number): (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>> {
  let timeoutId: ReturnType<typeof setTimeout> | null = null;
  let resolveList: Array<(value: Awaited<ReturnType<T>>) => void> = [];

  return function (this: ThisParameterType<T>, ...args: Parameters<T>) {
    return new Promise<Awaited<ReturnType<T>>>((resolve) => {
      if (timeoutId) {
        clearTimeout(timeoutId);
      }

      resolveList.push(resolve);

      timeoutId = setTimeout(() => {
        const result = func.apply(this, args);
        resolveList.forEach(resolve => resolve(result));
        resolveList = [];
      }, delay);
    });
  };
}

export function getUaInfo() {
  const userAgent = navigator.userAgent
  const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent)
  const isWindows = /Windows/i.test(userAgent)
  const isMac = /Macintosh/i.test(userAgent)
  const isLinux = /Linux/i.test(userAgent);
  return {
    isMobile,
    isWindows,
    isMac,
    isLinux,
  }
}

export function isMobile(paramsUserAgent?: string): boolean {
  const userAgent = paramsUserAgent || navigator.userAgent || navigator.vendor || window.opera;
  const mobileRegex = /android|iPad|iPhone|iPod|blackberry|iemobile|opera mini|mobile/i;
  return mobileRegex.test(userAgent);
}

export const isEffectiveValue = (val: any): boolean => {
  return val !== null && val !== undefined && val !== ''
}
// 过滤无效空值字段
export const filterInvalidValue = (obj: Record<string, any>, fn?: (value: any, key: string) => boolean) => {
  const result: Record<string, any> = {}
  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      const element = obj[key];
      if ( (!fn && isEffectiveValue(element)) || (fn && fn(element, key)) ) {
        result[key] = element
      }
    }
  }
  return result
}